//===================================================================================
// Copyright (c) 2008-2009 by www.TaoBao.com, All rights reserved.
//  391# wen'er road, HangZhou, China
//
// This software is the confidential and proprietary information of
// TaoBao.com, Inc. ("Confidential Information"). You shall not disclose
// such Confidential Information and shall use it only in accordance
// with the terms of the license agreement you entered into with TaoBao.com, Inc.
//===================================================================================
// File name: ResultDO.java
// Author: liupo
// Date: 2009-12-17 ����03:39:26
// Description:
// 		��
// Function List:
// 		1. ��
// History:
// 		1. ��
//===================================================================================

package org.summerframework.core.base.result;

import com.fasterxml.jackson.annotation.*;
import org.summerframework.core.base.dto.BaseDTO;
import org.springframework.util.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 接口调用返回参数封装对象
 *
 * @author 石超
 **/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResultDTO<T> implements java.io.Serializable {

    public static final ResultDTO<Boolean> DEFAULT_SUCCESS_RESULT = new ResultDTO<>();
    private static final long serialVersionUID = 7235889622424383753L;
    private Object id;
    /**
     * 结果返回的code
     */
    private ResultCode code = DefaultResultCode.SUCCESS;
    /**
     * 备注信息
     */
    @JsonIgnore
    private String errMsg;
    /**
     * 结果返回的业务数据
     */
    @JsonProperty("data")
    private T data;

    public static <T> ResultDTO<T> ok() {
        return (ResultDTO<T>) DEFAULT_SUCCESS_RESULT;
    }

    public static <T> ResultDTO<T> ok(T t) {
        return new ResultDTO<>(t);
    }

    public static <T> ResultDTO<T> ok(T t, BaseDTO baseDTO) {
        return new ResultDTO<>(t, baseDTO);
    }

    public static <T> ResultDTO<T> error(ResultCode code) {
        return new ResultDTO<>(code);
    }

    public static <T> ResultDTO<T> error(ResultCode code, String errMsg) {
        return new ResultDTO<>(code, errMsg);
    }

    public ResultDTO() {
        super();
    }

    public ResultDTO(ResultCode code) {
        putError(code);
    }

    public ResultDTO(ResultCode code, String errMsg) {
        putError(code, errMsg);
    }

    public ResultDTO(T t) {
        data = t;
    }


    public ResultDTO(T t, Long id) {
        data = t;
        setId(id);
    }

    public ResultDTO(T t, String id) {
        data = t;
        setId(id);
    }

    public ResultDTO(T t, BaseDTO id) {
        data = t;

        if (id != null) {
            this.id = id.getId();
        }
    }

    public ResultDTO(T t, Object id) {
        data = t;

        if (id != null) {
            try {
                Method method = id.getClass().getMethod("getId");
                this.id = method.invoke(id);
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }

    @JsonCreator
    public ResultDTO(@JsonProperty("code") Integer code, @JsonProperty("message") String errMsg) {
        this.code = DefaultResultCode.getInstance(code, errMsg);
        this.errMsg = errMsg;
    }

    public Object getId() {
        return id;
    }

    public void setId(Object id) {
        this.id = id;
    }

    /**
     * 操作是否成功
     *
     * @return
     */
    public boolean isSuccess() {
        return DefaultResultCode.SUCCESS == code;
    }

    /**
     * 设置操作成功
     */
    public void markSuccess() {
        this.code = DefaultResultCode.SUCCESS;
    }

    /**
     * 填充错误信息
     *
     * @param error
     */
    public void putError(ResultCode error) {
        this.putError(error, null);
    }

    /**
     * 填充错误信息
     *
     * @param error
     * @param msg
     */
    public void putError(ResultCode error, String msg) {
        if (error != null) {
            this.code = error;
            if (StringUtils.isEmpty(msg)) {
                this.errMsg = error.getMsg();
            } else {
                this.errMsg = msg;
            }
        }
    }

    /**
     * 填充错误信息
     *
     * @param error
     */
    public void putError(ResultDTO<?> error) {
        this.code = error.getCode();
        if (StringUtils.isEmpty(error.getErrMsg())) {
            this.errMsg = error.getCode().getMsg();
        } else {
            this.errMsg = error.getErrMsg();
        }
    }

    @JsonIgnore
    public ResultCode getCode() {
        return code;
    }

    public void setCode(ResultCode code) {
        this.code = code;
    }

    @JsonProperty("code")
    public int getResultCode() {
        return code.getCode();
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    @JsonProperty("message")
    public String getErrMsg() {
        return errMsg;
    }

    public void setErrMsg(String errMsg) {
        this.errMsg = errMsg;
    }
}
